#!/usr/bin/env python
# -*- coding: utf-8 -*-

#   Copyright (C) 2011  P.L. Lucas, P.L. del Castillo
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

# example basictreeview.py

import pygtk
pygtk.require('2.0')
import gtk
import cairo
import os
import shutil
import os.path
import shlex
import subprocess
import sys
import gobject
import pygst
pygst.require("0.10")
import gst
import cairo
import pangocairo
from xml.sax import make_parser
from xml.sax.handler import ContentHandler 
from fx import *
from transitions import *
from picture import *
from picturedialog import *
from videopropertiesdialog import *
from render import *
from terminal import *

class ProjectXMLHandler(ContentHandler):
	def __init__(self):
		self.pila=[]
		self.pictures=[]
		self.text=''
		self.attrs={}
		self.effect=[]
		self.effect_attrs={}
		self.videoProperties=None
		self.transition={}
	
	def startElement(self, name, attrs):
		self.pila.append(name)
		self.text=''
	
	def endElement(self, name):
		tag=self.pila.pop()
		last=None
		n=len(self.pila)-1
		if n>=0:
			last=self.pila[n]
		if last == 'picture':
			if name == 'effect':
				self.effect.append(self.effect_attrs)
				self.effect_attrs={}
			else:
				self.attrs[name]=self.text
		elif last == 'effect':
			self.effect_attrs[name]=self.text
		elif last == 'videoProperties':
			self.attrs[name]=self.text
		elif last == 'transition':
			self.transition[name]=self.text
		elif name=='picture':
			#Se crea una picture
			picture=Picture(None, None, None)
			picture.init_from_data(self.attrs, self.effect, self.transition, self.videoProperties)
			self.pictures.append(picture)
			#print self.attrs
			#print self.effect
			#print '..........'
			self.attrs={}
			self.effect=[]
			self.transition={}
		elif name=='videoProperties':
			self.videoProperties=VideoProperties(self.attrs['width'], self.attrs['height'])
			self.videoProperties.init_from_data(self.attrs)
			self.attrs={}
		self.text=''
	
	def characters (self, ch):
		self.text += ch

class BasicTreeViewExample:

	# close the window and quit
	def delete_event(self, widget, event=None, data=None):
		gtk.main_quit()
		return False

	def about_callback(self, menuitem):
		dialog=gtk.AboutDialog()
		dialog.set_name('Lukecastleslideshow')
		dialog.set_copyright("Copyright (C) 2011  P.L. Lucas, P.L. del Castillo")
		dialog.set_license("""This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""		)
		dialog.set_comments("This program lets you build slideshows by dropping your pictures and music.")
		dialog.set_logo( gtk.gdk.pixbuf_new_from_file(install_path+'/icons/lukecastleslideshow.svg') )
		
		dialog.connect ("response", lambda d, r: d.destroy())
		dialog.show()

	def add_picture_object(self, picture):
		treeselection = self.treeview.get_selection()
		(model, pathlist) = treeselection.get_selected_rows()
		iter=None
		if pathlist!=None and len(pathlist)>0:
			iter=self.treestore.get_iter(pathlist[len(pathlist)-1])
		self.treestore.disconnect(self.row_changed_signal_id)
		if iter==None:
			self.treestore.append(picture.get_row())
		else:
			self.treestore.insert_after(iter, picture.get_row())
		self.row_changed_signal_id=self.treestore.connect("row-deleted", self.update_time_callback, None)
		self.update_time()

	def add_picture(self, path):
		picture=Picture(path, 3.0, self.videoProperties)
		self.add_picture_object(picture)

	def add_picture_callback(self, menuitem):
		dialog=gtk.FileChooserDialog(title=None,action=gtk.FILE_CHOOSER_ACTION_OPEN, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
		filter = gtk.FileFilter()
		filter.set_name("All files")
		filter.add_pattern("*")
		dialog.add_filter(filter)

		filter = gtk.FileFilter()
		filter.set_name("Images")
		filter.add_mime_type("image/png")
		filter.add_mime_type("image/jpeg")
		filter.add_mime_type("image/gif")
		filter.add_pattern("*.png")
		filter.add_pattern("*.jpg")
		filter.add_pattern("*.gif")
		filter.add_pattern("*.tif")
		filter.add_pattern("*.xpm")
		dialog.add_filter(filter)
		
		dialog.set_filename(self.last_filename)
		dialog.set_select_multiple(True)

		response = dialog.run()
		if response == gtk.RESPONSE_OK:
		    #print dialog.get_filename(), 'selected'
		    for filename in dialog.get_filenames():
			    self.add_picture(filename)
			    self.last_filename=filename
		elif response == gtk.RESPONSE_CANCEL:
		    print 'Closed, no files selected'
		dialog.destroy()
	
	
	def add_colored_picture_callback(self, menuitem):
		dialog=gtk.ColorSelectionDialog("Select color")
		response=dialog.run()
		if response == gtk.RESPONSE_OK:
			picture=Picture(None, 3.0, self.videoProperties)
			color=dialog.colorsel.get_current_color()
			picture.set_color(float(color.red)/(65536.0),float(color.green)/(65536.0),float(color.blue)/(65536.0))
			self.add_picture_object(picture)
		elif response == gtk.RESPONSE_CANCEL:
		    print 'Closed, no color selected'
		dialog.destroy()
		
	def add_black_picture_callback(self, menuitem):
		picture=Picture(None, 3.0, self.videoProperties)
		picture.set_color(0.0,0.0,0.0)
		self.add_picture_object(picture)

	def properties_callback(self, menuitem):
		f=VideoPropertiesDialog(self.window,self.videoProperties)

	def save_callback(self, menuitem):
		dialog=gtk.FileChooserDialog(title=None,action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE,gtk.RESPONSE_OK))
		filename=self.project_file
		if filename==None:
			filename='file.xml'
		elif not filename.endswith('.xml'):
			filename+='.xml'
		dialog.set_filename(filename)
		response = dialog.run()
		if response == gtk.RESPONSE_OK:
			filename=dialog.get_filename()
			if not filename.endswith('.xml'):
				filename+='.xml'
			self.save(filename)
			self.project_file=dialog.get_filename()
		dialog.destroy()

	def save(self, file_name):
		f = open(file_name, 'w')
		f.write('<?xml version="1.0" encoding="UTF-8" ?>\n<project>\n')
		f.write(self.videoProperties.xml())
		it=self.treestore.get_iter_first()
		while it!=None:
			picture=self.treestore.get_value(it, 2)
			f.write(picture.xml())
			it=self.treestore.iter_next(it)
		f.write('</project>\n')
		f.close()

	def open_callback(self, menuitem):
		dialog=gtk.FileChooserDialog(title=None,action=gtk.FILE_CHOOSER_ACTION_OPEN, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
		response = dialog.run()
		if response == gtk.RESPONSE_OK:
			self.open_xml(dialog.get_filename())
			self.project_file=dialog.get_filename()
		dialog.destroy()

	def open_xml(self, file_name):
		parser = make_parser() 
		handler=ProjectXMLHandler()
		parser.setContentHandler(handler)
		parser.parse(open(file_name))
		self.videoProperties=handler.videoProperties
		self.treestore.disconnect(self.row_changed_signal_id)
		self.treestore.clear()
		for picture in handler.pictures:
			self.treestore.append(picture.get_row())
		self.row_changed_signal_id=self.treestore.connect("row-deleted", self.update_time_callback, None)
		self.update_time()


	def delete_picture_callback(self, menuitem):
		treeselection = self.treeview.get_selection()
		(model, pathlist) = treeselection.get_selected_rows()
		iter=None
		if pathlist!=None:
			pathlist.reverse()
			for i in pathlist:
				self.treestore.remove(self.treestore.get_iter(i))
				self.update_time()


	def picture_selected_callback(self, treeview, path, view_column, user_data):
		v=self.treestore.get_value(self.treestore.get_iter(path), 1)
		picture=self.treestore.get_value(self.treestore.get_iter(path), 2)
		#print v,'  ',picture.path
		dialog=PictureDialog(self.window, picture)
		i=0
		for v in picture.get_row():
			self.treestore.set_value(self.treestore.get_iter(path), i, v)
			i=i+1
		self.update_time()

	def drag_data_get_data(self, treeview, context, selection, target_id, etime):
		treeselection = treeview.get_selection()
		(model, pathlist) = treeselection.get_selected_rows()
		iter=self.treestore.get_iter(pathlist[0])
		data =model.get_value(iter, 2)
		self.drag_picture=data
		selection.set(selection.target, 8, 'Picture')

	
	def drag_data_received_callback(self, treeview, context, x, y, selection, info, timestamp):
		drop_info = treeview.get_dest_row_at_pos(x, y)
		model = treeview.get_model()
		row=None
		image_list=selection.data.split('\n')
		image_list.sort()
		if None!=self.treestore.get_iter_root():
			image_list.reverse()
		for i in image_list:
			if i!='':
				if i=='Picture':
					row=self.drag_picture.get_row()
				elif selection.data.startswith('file://'):
					picture=Picture(i[7:].strip(), 3.0, self.videoProperties)
					row=picture.get_row()
				else:
					context.finish(True, True, timestamp)
					return
				if drop_info:
					path, position = drop_info
					itera=self.treestore.get_iter(path)
					if (position == gtk.TREE_VIEW_DROP_BEFORE or position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE):
						model.insert_before(itera, row)
					else:
						model.insert_after(itera, row)
				else:
					model.append(row)
		if context.action == gtk.gdk.ACTION_MOVE:
			context.finish(True, True, timestamp)
		else:
			context.finish(True, True, timestamp)
		self.update_time()


	def update_time_callback(self, treemodel, path, user_param1):
		self.update_time()
		

	def update_time(self):
		self.treestore.disconnect(self.row_changed_signal_id)
		row=self.treestore.get_iter_root()
		t=0.0
		while row!=None:
			picture=self.treestore.get_value(row, 2)
			self.treestore.set_value(row, 3, t)
			t+=picture.duration
			row=self.treestore.iter_next(row)
			if picture.transition!=None and row!=None:
				t+=picture.transition.duration
		self.row_changed_signal_id=self.treestore.connect("row-deleted", self.update_time_callback, None)
		return t

	def get_pictures(self, pathlist=None):
		#self.treestore.disconnect(self.row_changed_signal_id)
		picture_list=[]
		if pathlist==None or (pathlist!=None and len(pathlist)==0):
			row=self.treestore.get_iter_root()
			while row!=None:
				picture=self.treestore.get_value(row, 2)
				picture_list.append(picture)
				row=self.treestore.iter_next(row)
		else:
			for path in pathlist:
				row=self.treestore.get_iter(path)
				picture=self.treestore.get_value(row, 2)
				picture_list.append(picture)
		return picture_list


	def play_callback(self, menuitem):
		#treeselection = self.treeview.get_selection()
		#(model, pathlist) = treeselection.get_selected_rows()
		#t=0.0
		#if len(pathlist)>0:
		#	row=self.treestore.get_iter(pathlist[0])
		#	t=float(self.treestore.get_value(row, 3))
		#print 't='+str(t)
		#render=Render(self.videoProperties, self.get_pictures(pathlist))
		#render.render_to_play(t)
		self.start_stop_callback(self, None)


	def render_to_file_callback(self, menuitem):
		if self.project_file=='':
			dialog=gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_NONE, 'Please: save your project first')
			dialog.run()
			return True
		file_name=None
		dialog=gtk.FileChooserDialog(title=None,action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
		filter = gtk.FileFilter()
		filter.set_name("All files")
		filter.add_pattern("*")
		dialog.add_filter(filter)

		filter = gtk.FileFilter()
		filter.set_name("Video")
		filter.add_mime_type("video/mpeg")
		filter.add_pattern("*.mpeg")
		filter.add_pattern("*.mpg")
		dialog.add_filter(filter)
		
		dialog.set_filename(self.output_file)

		response = dialog.run()
		if response == gtk.RESPONSE_OK:
			#print dialog.get_filename(), 'selected'
			file_name=dialog.get_filename()
			if not file_name.endswith('.mpeg'):
				file_name+='.mpeg'
			self.output_file=file_name
		elif response == gtk.RESPONSE_CANCEL:
			print 'Closed, no files selected'
	
		dialog.destroy()
		
		if file_name!=None:
			self.save(self.project_file)
			#command='gnome-terminal --command "bash -c \\"python \''+sys.argv[0]+'\' --process_to \''+file_name+'\' \''+self.project_file+'\' ; sleep 3 ; echo \'Finish\' ; read \\" "'
			command='python \''+sys.argv[0]+'\' \''+self.project_file+'\' --process_to \''+file_name+'\''
			terminal=Terminal()
			terminal.exec_command("python", ["python", sys.argv[0], self.project_file, "--process_to", file_name])
			print command
			#os.system(command)
			#print self.videoProperties.xml()
			#render=Render(self.videoProperties, self.get_pictures())
			#render.render_to_file(file_name)
			

	def start_stop_callback(self, w, render_to_file_ok=False, file_name=None):
		#Al final el render_to_file se hace con la clase Render usando ffmpeg.
		#Esta clase debería hacer el render a ficheros usando gstreamer, pero
		#me ha sido imosible conseguirlo. Sólo se podía hacer el render de vídeo
		#pero no incluía el sonido.
		print "start_stop_callback"
		if self.button.get_label() == "Start":
			self.button.set_label("Stop")
			treeselection = self.treeview.get_selection()
			(model, pathlist) = treeselection.get_selected_rows()
			t=0.0
			if len(pathlist)>0:
				row=self.treestore.get_iter(pathlist[0])
				t=float(self.treestore.get_value(row, 3))
			print 't='+str(t)
			self.seek_time=t
			self.seek_time_ok=True
			#pipe='filesrc location=Josh\ Woodward\ -\ Swansong.ogg ! oggdemux ! vorbisdec ! audioconvert ! alsasink                  '
			
			if not render_to_file_ok:
				width=72
				height=56
				fraction=12
				pipe='appsrc name=source blocksize='+str(width*height*4)+' ! video/x-raw-rgb,width=(int)'+str(width)+',height=(int)'+str(height)+',bpp=(int)32,depth=(int)32,framerate=(fraction)'+str(fraction)+'/1,red_mask='+str(0xff000000)+',green_mask='+str(0x00ff0000)+',blue_mask='+str(0x0000ff00)+',endianness=(int)4321 ! ffmpegcolorspace ! autovideosink name=sink  '
				if self.videoProperties.sound_path!=None and self.videoProperties.sound_path!='':
					pipe+='filesrc location="'+self.videoProperties.sound_path+'" name=sonido ! oggdemux ! vorbisdec ! audioconvert ! alsasink'
			else:
				width=self.videoProperties.width
				height=self.videoProperties.height
				fraction=self.videoProperties.framespersecond
				pipe='appsrc name=source blocksize='+str(width*height*4)+' ! video/x-raw-rgb,width=(int)'+str(width)+',height=(int)'+str(height)+',bpp=(int)32,depth=(int)32,framerate=(fraction)'+str(fraction)+'/1,red_mask='+str(0xff000000)+',green_mask='+str(0x00ff0000)+',blue_mask='+str(0x0000ff00)+',endianness=(int)4321 ! ffmpegcolorspace ! ffenc_mpeg4 ! avimux name=mux ! filesink name=salida location="'+str(file_name)+'" '
				if self.videoProperties.sound_path!=None and self.videoProperties.sound_path!='':
					pipe+=' filesrc location="'+self.videoProperties.sound_path+'" name=sonido ! oggdemux ! vorbisdec ! audioconvert ! ffenc_mp2 ! mux.'
			
			print pipe
			
			if self.player!=None:
				self.player.set_state(gst.STATE_NULL)
			
			self.player = gst.parse_launch(pipe)
			
			#if render_to_file_ok:
				# Se pone un reloj en el caso de pasar el archivo a un fichero
				#clock=gst.system_clock_obtain()
				#clock= ConvertClock()
				#self.player.get_by_name('source').set_clock( clock )
				#self.player.get_by_name('source').set_base_time( clock.get_time() )
				#clock.base_t=clock.get_time()
				#self.player.get_clock().set_active(True)
			bus = self.player.get_bus()
			bus.add_signal_watch()
			bus.enable_sync_message_emission()
			bus.connect("message", self.on_message_callback)
			bus.connect("sync-message::element", self.on_sync_message_callback)
		
			self.player.get_by_name('source').connect("need-data", self.need_data_callback)
			
			self.videoProperties.demoOk=not render_to_file_ok
			self.render=Render(self.videoProperties, self.get_pictures(pathlist))
			self.render.render_to_play(t)
			self.render.render_start()
			self.player.set_state(gst.STATE_PLAYING)
		else:
			self.player.set_state(gst.STATE_NULL)
			self.button.set_label("Start")
			self.render.render_end()
			self.videoProperties.demoOk=False
		
						
	def on_message_callback(self, bus, message):
		t = message.type
		if t == gst.MESSAGE_EOS:
			self.player.set_state(gst.STATE_NULL)
			self.button.set_label("Start")
		elif t == gst.MESSAGE_ERROR:
			err, debug = message.parse_error()
			print "Error: %s" % err, debug
			self.player.set_state(gst.STATE_NULL)
			self.button.set_label("Start")
	
	def on_sync_message_callback(self, bus, message):
		if message.structure is None:
			return
		message_name = message.structure.get_name()
		if message_name == "prepare-xwindow-id":
			imagesink = message.src
			imagesink.set_property("force-aspect-ratio", True)
			gtk.gdk.threads_enter()
			imagesink.set_xwindow_id(self.movie_window.window.xid)
			gtk.gdk.threads_leave()
	
	def demuxer_callback(self, demuxer, pad):
		if pad.get_property("template").name_template == "video_%02d":
			qv_pad = self.queuev.get_pad("sink")
			pad.link(qv_pad)
		elif pad.get_property("template").name_template == "audio_%02d":
			qa_pad = self.queuea.get_pad("sink")
			pad.link(qa_pad)
	
	def need_data_callback(self,src,length):
		t=0.0
		if src.get_clock()==None:
			print "Sin reloj"
		elif src.get_clock()!=None and src.get_base_time()!=0:
			print "Se calcula el t1"
			t=float(src.get_clock().get_time()-src.get_base_time())/1000000000.0
		elif src.get_clock()!=None and self.videoProperties.sound_path!='':
			print "Se calcula el t2"
			if self.videoProperties.demoOk:
				print "Modo demo"
				t=float(src.get_clock().get_time())/1000000000.0
			else:
				t=float(src.get_clock().get_time()-src.get_clock().base_t)/1000000000.0
			if self.seek_time_ok:
				seek_ns = (self.seek_time * 1000000000.0)
				self.player.seek_simple(gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH, seek_ns)
				self.seek_time_ok=False
				print "Seek realizado"
			#t+=self.seek_time/1000000000.0
		else:
			print "Sin reloj útil "
			#t=float(src.get_clock().get_time()-src.get_clock().base_t)/1000000000.0
		
		#t = self.player.query_position(gst.FORMAT_TIME, None)[0]/1000000000.0
		print 'time='+str(t)
		pixbuf=self.render.render_at_time(t)
		if pixbuf!=None:
			pixels=pixbuf.get_pixels()
			print "LLega length="+str(length)+" pixels_length="+str(len(pixels))
			gstBuf= gst.Buffer(pixels)
			src.emit('push-buffer', gstBuf)
		else:
			print 'Final'
			src.emit("end-of-stream")
			self.player.set_state(gst.STATE_PAUSED)
			gtk.gdk.threads_enter()
			self.button.set_label("Start")
			self.render.render_end()
			self.videoProperties.demoOk=False
			gtk.gdk.threads_leave()

		
	
	def player_init(self):
		vbox = gtk.VBox()
		hbox = gtk.HBox()
		vbox.pack_start(hbox, False)
		self.button = gtk.Button("Start")
		hbox.pack_start(self.button, False)
		self.button.connect("clicked", self.start_stop_callback)
		self.movie_window = gtk.DrawingArea()
		vbox.add(self.movie_window)
		#pipe='filesrc location=Josh\ Woodward\ -\ Swansong.ogg ! oggdemux ! vorbisdec ! audioconvert ! alsasink                  '
		pipe='appsrc name=source blocksize='+str(72*56*4)+' ! video/x-raw-rgb,width=(int)72,height=(int)56,bpp=(int)32,depth=(int)32,framerate=(fraction)12/1,red_mask='+str(0xff000000)+',green_mask='+str(0x00ff0000)+',blue_mask='+str(0x0000ff00)+',endianness=(int)4321 ! ffmpegcolorspace ! autovideosink name=sink  '
		print pipe
		self.player = gst.parse_launch(pipe)
		
		bus = self.player.get_bus()
		bus.add_signal_watch()
		bus.enable_sync_message_emission()
		bus.connect("message", self.on_message_callback)
		bus.connect("sync-message::element", self.on_sync_message_callback)
		
		self.player.get_by_name('source').connect("need-data", self.need_data_callback)
		return vbox


	def menu_init(self):
		file_menu = gtk.Menu()    # Don't need to show menus

		# Create the menu items
		open_item = gtk.MenuItem("Open")
		open_item.connect_object("activate", self.open_callback, 'open')
		save_item = gtk.MenuItem("Save")
		save_item.connect_object("activate", self.save_callback, 'save')
		quit_item = gtk.MenuItem("Quit")

		# Add them to the menu
		file_menu.append(open_item)
		file_menu.append(save_item)
		file_menu.append(quit_item)

		# Attach the callback functions to the activate signal
		#open_item.connect_object("activate", menuitem_response, "file.open")
		#save_item.connect_object("activate", menuitem_response, "file.save")

		# We can attach the Quit menu item to our exit function
		quit_item.connect_object ("activate", self.delete_event, "file.quit")

		# We do need to show menu items
		open_item.show()
		save_item.show()
		quit_item.show()
		file_menu.show()
		
		edit_menu=gtk.Menu()
		add_item=gtk.MenuItem('Add picture')
		add_item.connect_object("activate", self.add_picture_callback, 'add_picture')
		delete_item=gtk.MenuItem('Delete picture')
		delete_item.connect_object("activate", self.delete_picture_callback, 'delete_picture')
		edit_menu.append(add_item)
		edit_menu.append(delete_item)
		#Se añaden los cuadros de colores
		edit_menu.append(gtk.SeparatorMenuItem())
		black_item=gtk.MenuItem('Add black picture')
		black_item.connect_object("activate", self.add_black_picture_callback, 'add_black_picture')
		edit_menu.append(black_item)
		color_item=gtk.MenuItem('Add colored picture')
		color_item.connect_object("activate", self.add_colored_picture_callback, 'add_colored_picture')
		edit_menu.append(color_item)
		
		project_menu=gtk.Menu()
		play_item=gtk.MenuItem('Play...')
		play_item.connect_object("activate", self.play_callback, 'play')
		project_menu.append(play_item)
		render_item=gtk.MenuItem('Render to file')
		render_item.connect_object("activate", self.render_to_file_callback, 'render_to_file')
		project_menu.append(render_item)
		properties_item=gtk.MenuItem('Project properties')
		properties_item.connect_object("activate", self.properties_callback, 'properties')
		project_menu.append(properties_item)
		
		help_menu=gtk.Menu()
		about_item=gtk.MenuItem('About')
		about_item.connect_object("activate", self.about_callback, 'about')
		help_menu.append(about_item)
		
		self.menu_bar = gtk.MenuBar()
		menu=gtk.MenuItem("File")
		menu.show()
		menu.set_submenu(file_menu)
		self.menu_bar.append(menu)
		menu=gtk.MenuItem("Edit")
		menu.show()
		menu.set_submenu(edit_menu)
		self.menu_bar.append(menu)
		menu=gtk.MenuItem("Project")
		menu.show()
		menu.set_submenu(project_menu)
		self.menu_bar.append(menu)
		menu=gtk.MenuItem("Help")
		menu.show()
		menu.set_submenu(help_menu)
		menu.set_right_justified(True)
		self.menu_bar.append(menu)
		self.vbox.pack_start(self.menu_bar, False)
		self.menu_bar.show()

	def __init__(self):
		self.videoProperties=VideoProperties(400,300)
		self.last_filename=''
		self.project_file=''
		self.output_file=''
		self.drag_picture=None
		# Create a new window
		self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
		self.window.set_icon(gtk.gdk.pixbuf_new_from_file(install_path+'/icons/lukecastleslideshow.svg'))
		self.window.set_title("Lukecastleslideshow")

		self.window.set_size_request(300, 400)

		self.window.connect("delete_event", self.delete_event)

		# create a TreeStore with one string column to use as the model
		self.treestore = gtk.ListStore(gtk.gdk.Pixbuf, 'gfloat', object, 'gfloat')

		# we'll add some data now - 4 rows with 3 child rows each
		#        for parent in range(4):
		#            im=gtk.Image()
		#            im.set_from_file('olas.jpg');
		#            pix=im.get_pixbuf()
		#            height=pix.get_height()
		#            width=pix.get_width()
		#            pix=pix.scale_simple(64*width/height,64,gtk.gdk.INTERP_HYPER)
		#            picture=Picture('olas.jpg', parent, self.videoProperties)
		#            piter = self.treestore.append(picture.get_row())
		    
		# create the TreeView using treestore
		self.treeview = gtk.TreeView(self.treestore)
		self.treeview.set_reorderable(True)
		treeselection = self.treeview.get_selection()
		treeselection.set_mode(gtk.SELECTION_MULTIPLE)

		# create the TreeViewColumn to display the data
		self.tvcolumn = gtk.TreeViewColumn('Column 0')

		# add tvcolumn to treeview
		self.treeview.append_column(self.tvcolumn)

		# create a CellRendererText to render the data
		self.cell = gtk.CellRendererPixbuf()

		# add the cell to the tvcolumn and allow it to expand
		self.tvcolumn.pack_start(self.cell, True)

		# set the cell "text" attribute to column 0 - retrieve text
		# from that column in treestore
		self.tvcolumn.add_attribute(self.cell, 'pixbuf', 0)

		# make it searchable
		self.treeview.set_search_column(0)

		# Allow sorting on the column
		#self.tvcolumn.set_sort_column_id(0)

		# Allow drag and drop reordering of rows
		#self.treeview.set_reorderable(True)

		# create the TreeViewColumn to display the data
		self.tvcolumn = gtk.TreeViewColumn('Duration(s)')

		# add tvcolumn to treeview
		self.treeview.append_column(self.tvcolumn)

		# create a CellRendererText to render the data
		self.cell = gtk.CellRendererText()

		# add the cell to the tvcolumn and allow it to expand
		self.tvcolumn.pack_start(self.cell, True)

		# set the cell "text" attribute to column 0 - retrieve text
		# from that column in treestore
		self.tvcolumn.add_attribute(self.cell, 'text', 1)


		# create the TreeViewColumn to display the data
		self.tvcolumn = gtk.TreeViewColumn('Time(s)')

		# add tvcolumn to treeview
		self.treeview.append_column(self.tvcolumn)

		# create a CellRendererText to render the data
		self.cell = gtk.CellRendererText()

		# add the cell to the tvcolumn and allow it to expand
		self.tvcolumn.pack_start(self.cell, True)

		# set the cell "text" attribute to column 0 - retrieve text
		# from that column in treestore
		self.tvcolumn.add_attribute(self.cell, 'text', 3)

		self.treeview.connect("row-activated", self.picture_selected_callback, None)
		self.row_changed_signal_id=self.treestore.connect("row-deleted", self.update_time_callback, None)

		self.TARGETS = [
		      ('MY_TREE_MODEL_ROW', gtk.TARGET_SAME_WIDGET, 0),
		      ('text/plain', 0, 1),
		      ('TEXT', 0, 2),
		      ('STRING', 0, 3),
		      ]
		self.treeview.enable_model_drag_source( gtk.gdk.BUTTON1_MASK, self.TARGETS, gtk.gdk.ACTION_DEFAULT|gtk.gdk.ACTION_MOVE)
		self.treeview.enable_model_drag_dest(self.TARGETS,  gtk.gdk.ACTION_DEFAULT)
		self.treeview.connect("drag-data-received", self.drag_data_received_callback)
		self.treeview.connect("drag_data_get", self.drag_data_get_data)

		self.vbox=gtk.VBox()
		self.window.add(self.vbox)
		self.vbox.show()
		self.menu_init()
		hbox=gtk.HPaned()
		self.vbox.pack_start(hbox)
		self.scroll=gtk.ScrolledWindow()
		self.scroll.add(self.treeview)
		hbox.pack1(self.scroll)
		hbox.pack2(self.player_init())

		self.window.show_all()

def main():
	gtk.gdk.threads_init()
	gtk.main()


def print_help():
	print """
Video Podium is a simple GUI to build video-presentations from jpeg pictures.
video-podium [args] [file]
Options:
--help	This help
--process_to output_file	Process to output file
--pause	Pause at finish
	"""


if __name__ == "__main__":
	#Command line arguments are readed
	file_name=''
	output_file=''
	processOk=False
	state=0
	#states:
	#0 normal: looking for arguments or files
	#1 looking for output_file
	for arg in sys.argv:
		if state==0:
			if arg=='--process_to':
				state=1
			elif arg=='--help':
				state=-1
			elif arg=='--pause':
				state=-1
			else:
				file_name=arg
		elif state==1:
			output_file=arg
			processOk=True
			state=0
	if state==0:
		if output_file!='' and file_name!='':
			#Process file
			parser = make_parser() 
			handler=ProjectXMLHandler()
			parser.setContentHandler(handler)
			parser.parse(open(file_name))
			render=Render(handler.videoProperties, handler.pictures)
			render.render_to_file(output_file)
			print "\n\nRender finish...\n\n"
		else:
			#Show GUI
			tvexample = BasicTreeViewExample()
			main()
	else:
		print_help()
